home *** CD-ROM | disk | FTP | other *** search
-
-
-
- 212
-
- CHAPTER 20 - CONTROL STRUCTURES
-
-
-
- Control structures are things like 'for', 'do', 'while' and 'if'
- that you have in high level languages. It is possible to do these
- things in assembler language if you want. They are included here
- so if you ever want to use them at this level, you will have a
- template on how to set them up.
-
- All the examples will use integers only. If you have real
- numbers:
-
- if ( variable < 3.891 )
- x = 4 * y ;
-
- it is too difficult to implement on the 8086. Of course, if you
- have an 8087, it's a piece of cake.
-
-
- IF
-
- IF is the easiest and it will illustrate how we are going to set
- up our labels. Let's take that first example. Since it is a waste
- of space to define variables over and over, we will assume that
- all variables are words, not bytes. The examples will all be
- written in C.
-
- if (variable < 7)
- {
- x = 4 + y ;
- }
-
- The assembler code looks like this:
-
- if1: ;----------------
- cmp variable, 7
- jge end_if1
-
- mov x, 4
- mov ax, y
- add x, ax
- end_if1: ;----------------
-
- All labels will look like variations of this. The control words
- will be the labels.{1} They will have a unique number for each
- block so you can write as many different blocks as you want; the
- label that signals the end of the block will be the word 'end_'
- followed by the control word. The semicolon with the line is a
- ____________________
-
- 1. The words 'if' and 'endif' are Microsoft macro directives,
- so if you use them without a tag number, you will get some
- bizarre code indeed.
-
- ______________________
-
- The PC Assembler Tutor - Copyright (C) 1989 Chuck Nelson
-
-
-
-
- Chapter 20 - Control Structures 213
- _______________________________
-
- comment, and it is used for visual separation.
-
- By using a different number each time, you may nest as deeply as
- you want, though the code will be pretty unreadable:
-
- if (variable < 7 )
- {
- if ( x > 9 )
- {
- if ( z == 0 )
- {
- y = 12 ;
- }
- q = 5 ;
- }
- r = 7 ;
- }
-
- becomes:
-
- if1: ;---------------
- cmp variable, 7
- jge end_if1
-
- if2: ;---------------
- cmp x, 9
- jle end_if2
-
- if3: ;---------------
- cmp z, 0
- jne end_if3
-
- mov y, 12
- end_if3: ;-----------
- mov q, 5
- end_if2: ;-----------
- mov r, 7
- end_if1: ;-----------
-
-
- With the Microsoft assembler, you don't need to have the labels
- start at the beginning of the line, but they MUST be the first
- thing on the line. You can indent them:
-
- if1: ; --------------
- cmp variable, 7
- jge end_if1
-
- if2: ;-------------
- cmp x, 9
- jle end_if2
-
- if3: ;------------
- cmp z, 0
- jne end_if3
-
- mov y, 12
-
-
-
-
- The PC Assembler Tutor 214
- ______________________
-
- end_if3: ;--------
- mov q, 5
- end_if2: ;---------
- mov r, 7
- end_if1: ;---------
-
- You will notice that they are all compares and jumps using
- reverse logic. If the condition is NOT true, then we jump. If it
- is true, we just go on. What about IF ELSE? It looks almost the
- same.
-
- if ( j < 12 )
- {
- y = 19 ;
- }
- else
- {
- z = 25 ;
- }
-
- We get:
-
- if16: ;----------------
-
- cmp j, 12
- jge else16
-
- mov y, 19
- jmp end_if16
-
- else16:
- mov z, 25
- end_else16:
- end_if16: ;---------------
-
- We jump to another part inside the block, and throw in a JMP
- after the IF part.
-
-
- WHILE
-
- WHILE is the same as IF except that at the end of the block, we
- jump back to the beginning.
-
- while ( j < 20 )
- {
- j = j + 1 ;
- }
-
- while25: ;------------
- cmp j, 20
- jge end_while25
-
- inc j
- jmp while25
- end_while25: ;-----------
-
-
-
-
-
- Chapter 20 - Control Structures 215
- _______________________________
-
-
- DO WHILE
-
- DO WHILE always goes through the code once. The decision process
- is at the end.
-
- do
- {
- k = k + 7 ;
- } while (k < 0) ;
-
-
- do_while74: ;------------
- add k, 7
-
- cmp k, 0
- jl do_while74
- end_do_while74: ;------------
-
- Notice that here the jump is a positive decision. If the
- condition is fulfilled, we jump back to the start, otherwise we
- fall through. What do you do with 'break' and 'continue'? {2}
- Let's put them in:
-
- do
- {
- k = k + 7 ;
- if ( y < 9 )
- {
- continue ;
- }
- j = j - 6 ;
- if ( z == 5 )
- {
- break ;
- }
- y = y * 2 ;
- } while ( j < 17) ;
-
- In assembler language, this becomes:
-
- do_while143: ;----------
- add k, 7
-
- if144: ;-----------
- cmp y, 9
- jge end_if144
-
- jmp continue143
- end_if144: ;-----------
-
- sub j, 6
- ____________________
-
- 2. For those of you who are not C people, BREAK breaks you out
- of the innermost loop. CONTINUE skips all the code till the end
- of the loop.
-
-
-
-
- The PC Assembler Tutor 216
- ______________________
-
-
- if145: ;-----------
- cmp z, 5
- jne end_if145
-
- jmp break143
- end_if145: ;-----------
-
- sal y, 1 ; shift left 1 = multiply by 2
- continue143:
- cmp j, 17
- jl do_while143
- end_do_while143:
- break143:
-
- In DO WHILE, CONTINUE is the label just before the decision
- process. BREAK is always the first label after the block. We can
- just use the label that marks the end of our block for the break.
- Instead of:
-
- jmp break143
-
- we can have:
-
- jmp end_do_while143
-
- From now on, we'll put in the continue and break, even if they
- aren't used. Once you are used to it, you can drop the break
- label and use the end of block label. Going back to the WHILE
- statement, we have:
-
- while25: ;------------
- cmp j, 20
- jge end_while25
-
- inc j
- continue25:
- jmp while25
- end_while25: ;-----------
- break25:
-
-
-
- FOR
-
- The FOR statement in C is more sophisticated than in other
- languages, but we will keep the example simple. It has 3 parts:
-
- for ( i = 11 ; i < 20 ; i = i + 1 )
-
- can be looked at as:
-
- for ( initialize ; test ; update )
-
- The reason that it is sophisticated is that it can have any
- number of things in the first and third parts.
-
-
-
-
-
- Chapter 20 - Control Structures 217
- _______________________________
-
- for ( i = 11, j = 27 z = 4 ; i < 20 ; k = k + 1, j = j/2)
-
- is legitimate. Therefore we need to set aside a block for the
- initialize part, a block for the test part, and a block for the
- update part. One question is whether we want the initialization
- inside the FOR label. I'm not doing it, but it is a possibility.
- Here's the C code.
-
- for ( i = 11 ; i < 20 ; i = i + 1 )
- {
- k = k + 9
- }
-
- And its corresponding assembler code:
-
- init217: ;---------------
-
- mov i, 11
- end_init217: ;------
- for217: ; ---------------
- test217:
- cmp i, 20
- jge end_for217
- end_test217: ;-----
-
- add k,9
-
- continue217:
- update217:
- inc i
- end_update217: ; ----
- jmp test217
- end_for217: ;-------------
- break217:
-
- My that's a lot of labels. In this example we would get rid of
- most of them because there is so little code, but if the block
- contained a lot of code they would be a help, not a hindrance.
- Remember, a label generates no code, so this makes no difference
- in the size of the object file. Some of the labels which are not
- targets of jumps could be made into comments.
-
- end_update217: ;----
-
- can become:
-
- ; end_update217 ----
-
- Whichever way looks better to you. Using comments instead of
- labels gives you a slightly faster compile time. Just make sure
- you don't change one that IS a target of a jump.
-
-
- SWITCH
-
- Finally there is the switch statement. If you don't know what it
- is, skip this section because it will probably be confusing.
-
-
-
-
- The PC Assembler Tutor 218
- ______________________
-
-
- switch ( k )
- {
- case 'A': x = x + 9 ;
- break ;
-
- case '&': y = y * 2 ;
- break ;
-
- case 'j': z = z - 7 ;
- break ;
- }
-
- We get the following:
-
- switch82: ;-----------------
-
- cmp k, 'A'
- jne test82_2
- jmp case82_1
- test82_2
- cmp k, '&'
- jne test82_3
- jmp case82_2
- test82_3
- cmp k, 'j'
- jne end_test82
- jmp case82_3
- end_test82:
- jmp deafult82
- ; ----------
-
- case82_1:
- add x, 9
- jmp break82
-
- case82_2:
- sal y, 1 ; multiply by 2
- jmp break82
-
- case82_3:
- sub z, 7
- jmp break82
-
- default82:
- jmp break82
-
- end_switch82: ;------------
- break82:
-
- It may look like there are unnecessary jumps at the beginning,
- but it is likely that in a real program some of the case
- statements would be more than +127 bytes away from the
- conditional jumps, so you need JMP, which can go anywhere in the
- segment.
-
-